﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using JetBrains.Annotations;
using Kaleida.ServiceMonitor.Model;

namespace Kaleida.ServiceMonitor.UI.NotificationPanels
{
    [PanelName("10' Summary")]
    public partial class TenFootNotificationPanel : UserControl, IModuleNotificationPanel
    {
        private IEnumerable<ScriptSourceMenuItem> scriptMenuItems = Enumerable.Empty<ScriptSourceMenuItem>();
        private Monitor monitor;

        public TenFootNotificationPanel()
        {
            InitializeComponent();
        }

        public void Initialise([NotNull] Monitor monitorInstance)
        {
            if (monitorInstance == null) throw new ArgumentNullException("monitorInstance");
            monitor = monitorInstance;
        }

        public void RefreshContent()
        {
            var presentation = monitor.State.DefaultPresentation;

            BackColor = monitor.CompiledModule.ColourationStrategy.GetNotificationColour(monitor.State);
            lbl10FootSymbol.Text = presentation.GetNotificationWord();
            lbl10FootDetail.Text = presentation.GetStateDetail();
            AdjustFontSizeToFit(lbl10FootSymbol);

            lblScriptName.Text = monitor.CompiledModule.Name;
        }

    	public string PanelName
    	{
			get { return "10' Summary - " + monitor.CompiledModule.Name; }
    	}

    	public Control GetPanelControl()
        {
            return this;
        }

        private void TenFootNotificationPanel_Resize(object sender, EventArgs e)
        {
            var isMini = Width < 400 || Height < 200;            
            
            lblScriptName.Font = new Font(FontFamily.GenericSansSerif, isMini ? 16 : 26);
        	lblScriptName.TextAlign = isMini ? ContentAlignment.TopCenter : ContentAlignment.MiddleCenter;
        	lblScriptName.Height = isMini ? 25 : 60;
            AdjustFontSizeToFit(lbl10FootSymbol);
            lbl10FootDetail.Height = isMini ? 48 : 56;
            lbl10FootDetail.Font = isMini ? new Font("Segoe UI", 7.5f) : new Font("Courier New", 8.25f);
        }

        private void AdjustFontSizeToFit(Label label)
        {
            using (Graphics g = CreateGraphics())
            {
                for (int point = 220; point >= 10; point--)
                {
                    var testFont = new Font(label.Font.Name, point);
                    SizeF size = g.MeasureString(label.Text, testFont);

                    const int paddingPx = 50;
                    if (size.Width + paddingPx < label.Width && size.Height + paddingPx < label.Height)
                    {
                        label.Font = testFont;
                        label.Visible = true;
                        return;
                    }
                }
            }

            label.Visible = false;
        }

        private void OnSelectScriptClicked(object sender, EventArgs e)
        {
            var menuItem = (ScriptSourceMenuItem)sender;

            monitor.Application.Workspace.CurrentScript = menuItem.Script;
        }

        private void contextMenu_Opening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            miStartMonitoring.Enabled = monitor.State.CanBeginMonitoring;
            miStopMonitoring.Enabled = monitor.State.IsMonitoring;
            miAcknowledgeErrors.Enabled = monitor.State.HasFailures;

            var allScripts = monitor.Application.Workspace.LoadedScripts;
            scriptMenuItems = allScripts.Select(i => new ScriptSourceMenuItem(i, OnSelectScriptClicked));
            miSelectScript.DropDownItems.Clear();
            miSelectScript.DropDownItems.AddRange(scriptMenuItems.Cast<ToolStripItem>().ToArray());
            miSelectScript.Enabled = allScripts.Any();
        }

        private void miStartMonitoring_Click(object sender, EventArgs e)
        {
            monitor.State.StartMonitoring();
        }

        private void miStopMonitoring_Click(object sender, EventArgs e)
        {
            monitor.State.StopMonitoring();
        }

        private void miAcknowledgeError_Click(object sender, EventArgs e)
        {
            monitor.AcknowledgeErrors();
        }
    }
}
